package com.adcc.ags.gms.user.controller;

import com.adcc.ags.gms.core.util.Constant;
import com.adcc.ags.gms.core.util.LogFactory;
import com.adcc.ags.gms.core.vo.ResultState;
import com.adcc.ags.gms.core.vo.ResultVO;
import com.adcc.ags.gms.mq.vo.QueueVO;
import com.adcc.ags.gms.user.entity.GWUser;
import com.adcc.ags.gms.user.service.GWUserService;
import com.adcc.ags.gms.user.vo.GWUserVO;
import com.adcc.utility.codec.MD5;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.List;

/**
 * 网关用户控制层
 */
@Controller
@RequestMapping(value = "/GWUser", produces= MediaType.APPLICATION_JSON_VALUE)
public class GWUserController {

    @Autowired
    private GWUserService gwUserService;

    @Autowired
    private LogFactory log;

    /**
     * 校验网关用户名称
     * @param userName
     * @return
     */
    @RequestMapping(value = "/checkGWUserName", method = RequestMethod.GET)
    public @ResponseBody ResultVO checkGWUserName(String userName) {
        ResultVO resultVO = new ResultVO();
        try{
            String strName = Strings.nullToEmpty(userName);
            Optional<Boolean> optional = gwUserService.isExistGWUserName(strName);
            if (optional.isPresent()) {
                if(optional.get()){
                    resultVO.setCode(0);
                    resultVO.setState(ResultState.FAILURE);
                    resultVO.setReason("用户名已存在");
                }
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        }catch (Exception ex){
            log.error(GWUserController.class, "checkGWUserName() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 校验网关用户名称
     * @param userId
     * @return
     */
    @RequestMapping(value = "/checkGWUserId", method = RequestMethod.GET)
    public @ResponseBody ResultVO checkGWUserId(String userId) {
        ResultVO resultVO = new ResultVO();
        try{
            String strName = Strings.nullToEmpty(userId);
            Optional<Boolean> optional = gwUserService.isExistGWUserId(strName);
            if (optional.isPresent()) {
                if(optional.get()){
                    resultVO.setCode(0);
                    resultVO.setState(ResultState.FAILURE);
                    resultVO.setReason("用户ID已存在");
                }
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        }catch (Exception ex){
            log.error(GWUserController.class,"checkGWUserId error()", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 初始化发送队列下拉框
     * @return
     */
    @RequestMapping(value = "/initSendQueueList", method = RequestMethod.GET)
    public @ResponseBody ResultVO initSendQueueList(){
        ResultVO resultVO = new ResultVO();
        try {
            // 用户配置的发送队列
            Optional<List<QueueVO>> optional = gwUserService.findUnusedRecvQueue();
            if(optional.isPresent()){
                resultVO.getData().put("queueVO", optional.get());
            }else {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        } catch (Exception ex) {
            log.error(GWUserController.class,"initSendQueueList() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 初始化发送队列下拉框
     * @return
     */
    @RequestMapping(value = "{id}/initSendQueueList", method = RequestMethod.GET)
    public @ResponseBody ResultVO initSendQueueListByEdit(@PathVariable long id,String name){
        ResultVO resultVO = new ResultVO();
        try {
            // 用户配置的发送队列
            Optional<List<QueueVO>> optional = gwUserService.findUnusedRecvQueue();
            if(optional.isPresent()){
                QueueVO vo = new QueueVO();
                vo.setId(id);
                vo.setName(name);
                optional.get().add(0,vo);
                resultVO.getData().put("queueVO", optional.get());
            }else {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        } catch (Exception ex) {
            log.error(GWUserController.class,"initSendQueueListByEdit() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 取得所有接收队列列表
     * @return
     */
    @RequestMapping(value = "/initRecvQueueList", method = RequestMethod.GET)
    public @ResponseBody ResultVO initRecvQueueList(){
        ResultVO resultVO = new ResultVO();
        try {
            // 用户配置的接收队列
            Optional<List<QueueVO>> optional = gwUserService.findUnusedQueue();
            if(optional.isPresent()){
                resultVO.getData().put("queueVO", optional.get());
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        } catch (Exception ex) {
            log.error(GWUserController.class,"initRecvQueueList() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 取得所有接收队列列表(编辑模式)
     * @param id
     * @param name
     * @return
     */
    @RequestMapping(value = "{id}/initRecvQueueList", method = RequestMethod.GET)
    public @ResponseBody ResultVO initRecvQueueList(@PathVariable long id,String name){
        ResultVO resultVO = new ResultVO();
        try {
            // 用户配置的接收队列
            Optional<List<QueueVO>> optional = gwUserService.findUnusedQueue();
            if(optional.isPresent()){
                QueueVO vo = new QueueVO();
                vo.setId(id);
                vo.setName(name);
                optional.get().add(0,vo);
                resultVO.getData().put("queueVO", optional.get());

            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        } catch (Exception ex) {
            log.error(GWUserController.class,"initRecvQueueList() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 根据用户名称查找用户
     * @param name
     * @param currentPage
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/findGWUserByName", method = RequestMethod.GET)
    public @ResponseBody ResultVO<GWUserVO> findGWUserByName(String name,int currentPage, int pageSize){
        ResultVO resultVO = new ResultVO();
        try {
            List<GWUserVO> voList = Lists.newArrayListWithExpectedSize(1000);
            Optional<PageInfo<GWUser>> optional = gwUserService.findGWUserByName(name, currentPage, pageSize);
            if(optional.isPresent()){
                if(optional.get().getList() != null && optional.get().getList().size() > 0){
                    for(GWUser gwUser : optional.get().getList()){
                        GWUserVO vo = new GWUserVO(gwUser);
                        voList.add(vo);
                    }
                }
                resultVO.getData().put("gwUserVO", voList);
                resultVO.setPageInfo(optional.get());
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        } catch (Exception ex) {
            log.error(GWUserController.class,"findGWUserByName() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 创建网关用户
     * @param vo
     * @return
     */
    @RequestMapping( method = RequestMethod.POST)
    public @ResponseBody ResultVO createGWUser(GWUserVO vo) {
        ResultVO resultVO = new ResultVO();
        try {
            Optional<Boolean> optional = gwUserService.createGWUser(vo);
            if (!optional.isPresent()) {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
        } catch (Exception e) {
            log.error(GWUserController.class, "createGWUser() error", e);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 更新网关用户
     * @param id
     * @param vo
     * @return
     */
    @RequestMapping(value ="/{id}",method = RequestMethod.PUT)
    public @ResponseBody ResultVO updateGWUser(@PathVariable("id") long id, @RequestBody GWUserVO vo) {
        ResultVO resultVO = new ResultVO();
        try {
            Optional<Boolean> optional = gwUserService.updateGWUser(vo);
            if (!optional.isPresent()) {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
        } catch (Exception e) {
            log.error(GWUserController.class, "updateGWUser() error", e);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 删除网关用户
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public @ResponseBody ResultVO deleteGWUser(@PathVariable("id") long id,Boolean flag) {
        ResultVO resultVO = new ResultVO();
        try {
            Optional<Boolean> optional = gwUserService.deleteGWUser(id,flag);
            if(!optional.isPresent()) {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
        } catch (Exception e) {
            log.error(GWUserController.class, "deleteGWUser() error", e);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 上线网关用户
     * @param id
     * @return
     */
    @RequestMapping(value = "{id}/gwUserOnline", method = RequestMethod.POST)
    public @ResponseBody ResultVO gwUserOnline(@PathVariable long id) {
        ResultVO resultVO = new ResultVO();
        try{
            Optional<Boolean> optional = gwUserService.gwUserOnline(id);
            if(optional.isPresent()){
                if(!optional.get()){
                    resultVO.setCode(-1);
                    resultVO.setState(ResultState.FAILURE);
                    resultVO.setReason("用户不存在");
                }
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
        }catch (Exception ex){
            log.error(GWUserController.class,"gwUserOnline() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 下线网关用户
     * @param id
     * @return
     */
    @RequestMapping(value = "{id}/gwUserOffline", method = RequestMethod.POST)
    public @ResponseBody ResultVO gwUserOffline(@PathVariable long id) {
        ResultVO resultVO = new ResultVO();
        try{
            Optional<Boolean> optional = gwUserService.gwUserOffline(id);
            if(optional.isPresent()){
                if(!optional.get()){
                    resultVO.setCode(-1);
                    resultVO.setState(ResultState.FAILURE);
                    resultVO.setReason("用户不存在");
                }
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
        }catch (Exception ex){
            log.error(GWUserController.class, "gwUserOffline() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 更新网关用户配置(推送操作)
     * @return
     */
    @RequestMapping(value = "/updateUserList", method = RequestMethod.GET)
    public @ResponseBody ResultVO updateUserList() {
        ResultVO resultVO = new ResultVO();
        try{
            Optional<Boolean> optional = gwUserService.updateUserList();
            if (optional.isPresent() && optional.get()) {
                resultVO.setCode(0);
                resultVO.setState(ResultState.SUCCESS);
            } else {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GW_UPDATE_GWUSER_ERROR);
            }
        }catch (Exception ex){
            log.error(GWUserController.class,"updateUserList() error",ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 下载网关用户配置
     * @param response
     */
    @RequestMapping(value = "/downloadUserList", method = RequestMethod.GET)
    public void downloadUserList(HttpServletResponse response) {
        XMLWriter xw = null;
        StringWriter sw = null;
        InputStream is = null;
        OutputStream os = null;
        try {
            int intLength = -1;
            byte[] data = null;
            byte[] buffer = new byte[1024];
            Document document = gwUserService.createUserList();
            if(document != null){

                // 设置Http文件下载协议
                response.setCharacterEncoding("UTF-8");
                response.setContentType(MediaType.MULTIPART_FORM_DATA.toString());
                response.setHeader("Content-Disposition","attachment;fileName=" + Constant.USERLIST_FILE_NAME);

                // 输出文件流
                sw = new StringWriter();
                xw = new XMLWriter(sw, OutputFormat.createPrettyPrint());
                xw.write(document);
                data = sw.getBuffer().toString().getBytes();
                is = new ByteInputStream(data,data.length);
                os = response.getOutputStream();
                while ((intLength = is.read(buffer, 0, buffer.length)) > -1){
                    os.write(buffer,0,intLength);
                    os.flush();
                }
            }
        } catch (Exception ex) {
            log.error(GWUserController.class,"downloadUserList() error",ex);
        }finally {
            try{
                if(os != null){
                    os.close();
                }
                if(is != null){
                    is.close();
                }
                if(sw != null){
                    sw.close();
                }
                if(xw != null){
                    xw.close();
                }
            }catch (Exception ex){
                log.error(GWUserController.class,"downloadUserList() close IO error",ex);
            }
        }
    }

    /**
     * 同步网关用户配置
     * @param response
     */
    @RequestMapping(value = "/syncUserList", method = RequestMethod.GET)
    public void syncUserList(@RequestParam("MD5")String md5,HttpServletResponse response) {
        XMLWriter xw = null;
        StringWriter sw = null;
        InputStream is = null;
        OutputStream os = null;
        try {
            int intLength = -1;
            byte[] data = null;
            byte[] buffer = new byte[1024];
            Document document = gwUserService.createUserList();
            if(document != null){
                String strMD5 = MD5.getMD5(document.asXML());
                if(!Strings.isNullOrEmpty(md5) && md5.equals(strMD5)){
                    return;
                }else{
                    // 设置Http文件下载协议
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType(MediaType.MULTIPART_FORM_DATA.toString());
                    response.setHeader("Content-Disposition","attachment;fileName=" + Constant.USERLIST_FILE_NAME);

                    // 输出文件流
                    sw = new StringWriter();
                    xw = new XMLWriter(sw, OutputFormat.createPrettyPrint());
                    xw.write(document);
                    data = sw.getBuffer().toString().getBytes();
                    is = new ByteInputStream(data,data.length);
                    os = response.getOutputStream();
                    while ((intLength = is.read(buffer, 0, buffer.length)) > -1){
                        os.write(buffer,0,intLength);
                        os.flush();
                    }
                }
            }
        } catch (Exception ex) {
            log.error(GWUserController.class, "syncUserList() error", ex);
        }finally {
            try{
                if(os != null){
                    os.close();
                }
                if(is != null){
                    is.close();
                }
                if(sw != null){
                    sw.close();
                }
                if(xw != null){
                    xw.close();
                }
            }catch (Exception ex){
                log.error(GWUserController.class,"syncUserList() close IO error",ex);
            }
        }
    }
}
